<!-- 
  工具函数

  isRef()
    判断一个数据是否为 ref 数据，返回一个 boolean 值
    const num1 = ref(1)
    const num2 = 2

    console.log('num1 isRef', isRef(num1)) // true
    console.log('num2 isRef', isRef(num2)) // false
  unref()
    可以对ref数据做解包的函数，传入一个ref数据会返回.value的值，否则返回原值
    const num1 = ref(1)
    const num2 = 2

    console.log('num1 unref', unref(num1)) // 1
    console.log('num2 unref', unref(num2)) // 2
  toRef()
    toRef(target, key)
    将一个响应式对象的某个属性转换成ref数据并返回，得到的值与原值是联通的。
    const state = reactive({
      name: '张三',
      age: 18
    })

    const name = toRef(state, 'name')
    console.log('name', name) // RefImpl { value: '张三' }
    
    state.name+='~'
    console.log(name.value) // '张三~'
    name.value+='~'
    console.log(state.name) // '张三~~'
  toRefs()
    toRefs(target)
    返回一个普通对象，该普通对象中的属性为原对象中有的属性，属性值将会转换成ref数据
    const state = reactive({
      name: '张三',
      age: 18
    })

    const obj = toRefs(state)
    // {
    //   name: { value: '张三' },
    //   age: { value: 18 }
    // }
    console.log('obj', obj)

    const { name, age } = toRefs(state)
    name.value = '里斯'
    console.log('state.name', state.name) // ‘里斯’
    state.name = '王五'
    console.log('name', name.value) // '王五'

    age.value = 20
    console.log('state.age', state.age) // 20
    state.age = 21
    console.log('age', age.value) // 21
  toValue()
    用来规范化一个可以是值、ref 或 getter 的参数。
    与 unref() 类似，但是多出了一个 getter 参数的支持
    const num1 = ref(1)
    const num2 = 1
    const num3 = () => {
      console.log('num3 getter')
      return 3
    }

    console.log(unref(num1)) // 1
    console.log(unref(num2)) // 1
    console.log(unref(num3)) // () => { console.log('num3 getter')return 3}

    console.log(toValue(num1)) // 1
    console.log(toValue(num2)) // 1
    console.log(toValue(num3)) // 3
  isProxy()
    判断数据是否为一个 Proxy 
  isReactive()
    判断数据是否为一个 Reactive
  isReadonly()
    判断数据是否为一个 Readonly
 -->

<template>
  <div>
    <h1>工具函数</h1>
    <p>{{ state.name }}</p>
    <p>{{ state.age }}</p>
    <p>{{ state.address.text }}</p>
    <p>name: {{ name }}</p>
    <p>age: {{ age }}</p>

    <button @click="state.name = '里斯'">change</button>
    <button @click="state.age++">change</button>
  </div>
</template>

<script>
import {
  reactive,
  toRef,
  toRefs,
  toValue,
  unref,
  ref,
  isProxy,
  isReactive,
  readonly,
  isReadonly,
onMounted
} from 'vue'

export default {
  setup() {
    const origin = {
      name: '张三',
      age: 18
    }
    const myProxy = new Proxy(origin, {
      get(target, key) {
        // return target[key]
        return Reflect.get(target, key)
      },
      set(target, key, value) {
        // return target[key] = value
        return Reflect.set(target, key, value)
      }
    })
    const myReactive = reactive(origin)
    const myCopy = readonly(myReactive)
    console.log('origin isProxy', isProxy(origin)) // false
    // false, 自己创建出的 proxy 不能给它判断，必须是Vue3内部的 reactive() readonly() shallowReactive() shallowReadonly()
    console.log('myProxy isProxy', isProxy(myProxy))
    console.log('myReactive isProxy', isProxy(myReactive)) // true
    console.log('myReactive isReactive', isReactive(myReactive)) // true
    console.log('myCopy isReadonly', isReadonly(myCopy)) // true
    console.log('myProxy', myProxy)

    // const num1 = ref(1)
    // const num2 = 1
    // const num3 = () => {
    //   console.log('num3 getter')
    //   return 3
    // }

    // console.log(unref(num1)) // 1
    // console.log(unref(num2)) // 1
    // console.log(unref(num3)) // () => { console.log('num3 getter')return 3}

    // console.log(toValue(num1)) // 1
    // console.log(toValue(num2)) // 1
    // console.log(toValue(num3)) // 3

    // const state = reactive({
    //   name: '张三',
    //   age: 18,
    //   address: {
    //     text: '深圳市'
    //   }
    // })

    // return {
    //   state,
    //   // name: toRef(state, 'name'),
    //   // age: toRef(state, 'age'),
    //   // address: toRef(state, 'address')
    //   ...toRefs(state)
    // }
  }
}
</script>
